from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta


def nearest_last_monday(date):
    """
    往前找最近的周一
    """
    # 转换为星期几的整数表示（0=星期一, 1=星期二, ..., 6=星期日）
    day_of_week = date.weekday()
    # 计算需要往前调整的天数
    delta_days = day_of_week - 0  # 0代表星期一
    # 如果今天是周一或之前，则不需要调整
    if delta_days <= 0:
        return date
    else:
        # 返回最近的周一
        return date - timedelta(days=delta_days)


def nearest_last_friday(date):
    """
    往前找最近的周五
    """
    # 转换为星期几的整数表示（0=星期一, 1=星期二, ..., 4=星期五, 5=星期六, 6=星期日）
    weekday = date.weekday()
    # 计算到最近的周五的天数差
    days_to_friday = weekday - 4 if weekday >= 4 else weekday + 3
    # 返回最近的周五的日期
    return date - timedelta(days=days_to_friday)


def nearest_next_friday(date):
    """
    往后找最近的周五
    """
    # 计算到周五的天数差
    days_to_friday = (4 - date.weekday()) % 7
    # 如果今天就是周五，则不需要增加天数
    if days_to_friday == 0:
        return date
    # 返回最近的周五的日期
    return date + timedelta(days_to_friday)


def nearest_last_last_day_of_month(date):
    """
    往前找最近的月末日
    """
    if (date + timedelta(days=1)).day == 1:
        return date
    return nearest_last_first_day_of_month(date) - timedelta(days=1)


def nearest_next_first_day_of_month(date):
    """
    往后找最近的月首日
    """
    if date.day == 1:
        return date
    return (date + relativedelta(months=1)).replace(day=1)


def nearest_last_first_day_of_month(date):
    """
    往后找最近的月末日
    """
    return date.replace(day=1)


def nearest_last_first_day_of_quarter(date):
    """
    往前找最近的季度首日
    """
    year = date.year
    month = date.month
    quarter_start_month = (month - 1) // 3 * 3 + 1
    return datetime(year, quarter_start_month, 1).date()


def nearest_last_last_day_of_quarter(date):
    """
    往前找最近的季度首日
    """
    if is_last_day_of_quarter(date):
        return date
    return nearest_last_first_day_of_quarter(date) - relativedelta(days=1)


def is_last_day_of_quarter(date):
    """
    是否为季度最后一日
    """
    next_day = (date + relativedelta(days=1))
    return next_day == nearest_last_first_day_of_quarter(next_day)


def is_last_day_of_year(date):
    """
    是否为年度最后一日
    """
    return date.month == 12 and date.day == 31


def nearest_last_last_day_of_year(date):
    """
    往前找最近的年度末日
    """
    if is_last_day_of_year(date):
        return date
    return datetime(date.year - 1, 12, 31).date()


def nearest_last_first_day_of_year(date):
    """
    往前找最近的年度首日
    """
    return datetime(date.year, 1, 1).date()
